﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtConcurrent>
#include "protocol/serial.h"
#include "dialog_mc_update.h"
#include "dialog_log.h"
#include "utils/FILEWR.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow),
    b_serial_opend(false)
    ,
    gui_colors {
        /* Monochromatic for axes and ui */
        QColor (48,  47,  47,  255), /**<  0: qdark ui dark/background color */
        QColor (80,  80,  80,  255), /**<  1: qdark ui medium/grid color */
        QColor (170, 170, 170, 255), /**<  2: qdark ui light/text color */
        QColor (48,  47,  47,  200)  /**<  3: qdark ui dark/background color w/transparency */
      }
{
    setWindowIcon(QIcon(":/image/mc.png"));
    ui->setupUi(this);
    ui->tabWidget_2->setCurrentIndex(0);
    this->setContextMenuPolicy(Qt::CustomContextMenu);
    mc_update = nullptr;
    mc_logger = nullptr;
    box_update = nullptr;
    connect(this, &QWidget::customContextMenuRequested, this, &MainWindow::my_menu_display);
    right_menu = new QMenu(this);
    life_time = 0;
    PlotInit();
    // 隐藏状态栏下方三角形
    ui->statusBar->setSizeGripEnabled(false);
    ui->statusBar->setStyleSheet("font-size:18px;");
    PermanentLab = new QLabel(this);
    PermanentLab->setMinimumHeight(20);
    PermanentLab->setFrameStyle(QFrame::Box | QFrame::Sunken);
    ui->statusBar->addPermanentWidget(PermanentLab);
    ShowPermanentMessage("串口未连接", Qt::red);
    ui->tabWidget->setEnabled(false);
    ui->tabWidget_2->setEnabled(false);
    serial = new Serial();
    serial_max_frame_size = 8;
    mc = new Controller(serial, 0x4D);
    box = new UsbBox(serial);
    open_force = false;
    ui->comboBox->addItems(serial->GethwPorts());
    ui->comboBox_mode->addItems(mc->GetCtrlModes());
    ui->lineEdit_input_vel->setVisible(true);//visiable when velocity mode
    connect (&updateTimer, SIGNAL (timeout()), this, SLOT (replot()));
    connect(mc, &Controller::contrl_status, this, &MainWindow::onMotorStsChanged);
    connect(mc, &Controller::plotDataSingal, this, &MainWindow::onPlatData);
    connect(serial, &Serial::portStatusChanged, this, [this](bool opened){
        b_serial_opend = opened;
        qDebug() << "serial:" << opened;
        if (opened) {
            ui->tabWidget->setEnabled(true);
            ui->tabWidget_2->setEnabled(true);
            ui->pushButton_serialOpen->setText("关闭");
            ShowPermanentMessage("串口已连接:" + ui->comboBox->itemText(ui->comboBox->currentIndex()), Qt::blue);
            updateTimer.start(10);
        }else {
            ui->tabWidget->setEnabled(false);
            ui->tabWidget_2->setEnabled(false);
            ui->pushButton_serialOpen->setText("打开");
            ShowPermanentMessage("串口未连接", Qt::red);
            updateTimer.stop();
        }
    });
}

void MainWindow::closeEvent(QCloseEvent *event){
    Q_UNUSED(event);
    if (mc_update) {
        mc_update->close();
    }
    if (mc_logger) {
        mc_logger->close();
    }
    if (box_update) {
        box_update->close();
    }
    MainWindow::close();
}

void MainWindow::my_menu_display(const QPoint &pos) {
    Q_UNUSED(pos);
    right_menu->clear();
    QAction *upgrade = new QAction("固件升级", this);
    QAction *log = new QAction("打开调试", this);
    QAction *boxup = new QAction("通信盒子升级", this);
    right_menu->addAction(upgrade);
    connect(upgrade, &QAction::triggered, this, [this](bool trigger){
        Q_UNUSED(trigger);
        mc_update = new Dialog_mc_update(box);
        mc_update->exec();
        delete mc_update;
        mc_update = nullptr;
    });
    right_menu->addSeparator();
    right_menu->addAction(log);
    connect(log, &QAction::triggered, this, [this](bool trigger){
        Q_UNUSED(trigger);
        mc_logger = new Dialog_log(mc);
        mc_logger->exec();
        delete mc_logger;
        mc_logger = nullptr;
    });

    right_menu->addSeparator();
    right_menu->addAction(boxup);
    connect(boxup, &QAction::triggered, this, [this](bool trigger){
        Q_UNUSED(trigger);
        box_update = new Dialog_mc_update(box, 0);
        box_update->exec();
        delete box_update;
        box_update = nullptr;
    });
    right_menu->exec(QCursor::pos());
    disconnect(upgrade);
    disconnect(log);
    disconnect(boxup);
    qDebug() << "This is a test";
}

void MainWindow::onPlatData(unsigned mask, float p1, float p2, float p3, float p4){
    QList<float> list;
    list << p1 << p2 << p3 << p4;
    plotMan->DisplayData(mask, list, ui->spinPoints->value());
}

void MainWindow::replot()
{
    plotMan->replot();
}

void MainWindow::ShowPermanentMessage(QString message, QColor clr){
    QPalette pe;
    pe.setColor(QPalette::WindowText, clr);
    PermanentLab->setPalette(pe);
    PermanentLab->setText(message);
}

void MainWindow::ShowMessage(QString message, QColor clr){
    QPalette pe;
    pe.setColor(QPalette::WindowText, clr);
    ui->statusBar->setPalette(pe);
    ui->statusBar->showMessage(message);
}

void MainWindow::onMotorStsChanged(QString names){
    QList<QString> nlist = names.split(",");
    for (auto n : nlist ) {
        motStsChanged(n);
    }
}

void MainWindow::motStsChanged(QString name){
    if (name == "DQ_Current") {
        ui->label_Id->setText(QString::number(mc->dq_current[0]));
        ui->label_Iq->setText(QString::number(mc->dq_current[1]));
        float is = sqrtf(mc->dq_current[0]*mc->dq_current[0] + mc->dq_current[1]*mc->dq_current[1]);
        ui->label_Idq_Vector->setText(QString::number(is, 'f', 2));
    }else if (name == "DQ_Voltage") {
        ui->label_Vd->setText(QString::number(mc->dq_voltage[0]));
        ui->label_Vq->setText(QString::number(mc->dq_voltage[1]));
        float vs = sqrtf(mc->dq_voltage[0]*mc->dq_voltage[0] + mc->dq_voltage[1]*mc->dq_voltage[1]);
        ui->label_Vdq_Vector->setText(QString::number(vs, 'f', 2));
    }else if (name == "Power") {
        ui->label_speed->setText(QString::number(mc->rpm));
        ui->label_speed_km->setText(QString::number(Utils::rpm_to_speed(mc->rpm)));
        ui->label_dc_current->setText(QString::number(mc->dc_current));
        ui->label_dc_voltage->setText(QString::number(mc->dc_voltage));
        float power = mc->dc_current * mc->dc_voltage/1000.0f;
        power = roundf(power);
        ui->label_power->setText(QString::number(power, 'f', 2) + "Kw");
    }else if (name == "Status") {
        ui->label_status->setText(mc->b_start?"运行":"空闲");
        ui->label_mode->setText(Enum().name(mc->mode));
        if (ui->lineEdit_input_vel->isVisible() && mc->mode != Enum::Velocity) {
            ui->lineEdit_input_vel->setVisible(false);
        }else if (!ui->lineEdit_input_vel->isVisible() && mc->mode == Enum::Velocity) {
            ui->lineEdit_input_vel->setVisible(true);
        }
        QString err = "无";
        if (mc->err_mask != 0) {
            err ="";
            for (int i = 0; i < 32; i++) {
                if (mc->err_mask & (1<<i)) {
                    if (err == "") {
                        err = "E " + QString::number(i);
                    }else {
                        err = err + "|" + QString::number(i);
                    }
                }
            }
            QPalette pe;
            pe.setColor(QPalette::WindowText, Qt::red);
            ui->label_err_code->setPalette(pe);
        }else if (mc->warn_mask != 0){
            err ="";
            for (int i = 0; i < 32; i++) {
                if (mc->warn_mask & (1<<i)) {
                    if (err == "") {
                        err = "W " + QString::number(i);
                    }else {
                        err = err + "|" + QString::number(i);
                    }
                }
            }
            QPalette pe;
            pe.setColor(QPalette::WindowText, Qt::red);
            ui->label_err_code->setPalette(pe);
        }else {
            QPalette pe;
            pe.setColor(QPalette::WindowText, Qt::black);
            ui->label_err_code->setPalette(pe);
        }
        ui->label_err_code->setText(err);

        ui->label_lifetime->setText(QString::number(mc->life_time));

        life_time = mc->life_time;
    }
}

void MainWindow::on_pushButton_serialFlush_clicked()
{
    ui->comboBox->clear();
    ui->comboBox->addItems(serial->GethwPorts());
}


void MainWindow::on_pushButton_serialOpen_clicked()
{
    QString band = ui->lineEdit->text();
    if (band.isEmpty()) {
        return;
    }
    int i_band = band.toInt();
    QString com = ui->comboBox->itemText(ui->comboBox->currentIndex());
    if (!com.isEmpty()) {
        if (!b_serial_opend) {
            if (!serial->OpenPort(com, i_band, ui->checkBox_direct->isChecked())){
                ShowMessage("打开串口失败", Qt::red);
            }else {
                //ShowMessage("串口连接成功");
                //updateTimer.start(10);
            }
        }else {
            serial->ClosePort();
            //ShowMessage("串口已关闭", Qt::red);
            //updateTimer.stop();
        }
    }
}


void MainWindow::on_checkBox_direct_stateChanged(int arg1)
{
    if (arg1 == 2) {
        serial->DirectConnect(true);
    }else {
        serial->DirectConnect(false);
    }
}


void MainWindow::on_checkBox_phase_curr_stateChanged(int arg1)
{
    CheckSelectedBox(ui->checkBox_phase_curr, (arg1 > 0)?true:false);
}


void MainWindow::on_checkBox_phase_vol_stateChanged(int arg1)
{
    CheckSelectedBox(ui->checkBox_phase_vol, (arg1 > 0)?true:false);
}


void MainWindow::on_checkBox_in_torque_stateChanged(int arg1)
{

    CheckSelectedBox(ui->checkBox_in_torque, (arg1 > 0)?true:false);
}


void MainWindow::on_checkBox_out_torque_stateChanged(int arg1)
{

    CheckSelectedBox(ui->checkBox_out_torque, (arg1 > 0)?true:false);
}


void MainWindow::on_checkBox_in_vel_stateChanged(int arg1)
{

    CheckSelectedBox(ui->checkBox_in_vel, (arg1 > 0)?true:false);
}


void MainWindow::on_checkBox_mot_vel_stateChanged(int arg1)
{

    CheckSelectedBox(ui->checkBox_mot_vel, (arg1 > 0)?true:false);
}


void MainWindow::on_checkBox_mot_angle_stateChanged(int arg1)
{

    CheckSelectedBox(ui->checkBox_mot_angle, (arg1 > 0)?true:false);
}

void MainWindow::on_checkBox_dq_current_stateChanged(int arg1)
{
    CheckSelectedBox(ui->checkBox_dq_current, (arg1 > 0)?true:false);
}


void MainWindow::on_checkBox_dq_vol_stateChanged(int arg1)
{
    CheckSelectedBox(ui->checkBox_dq_vol, (arg1 > 0)?true:false);
}


void MainWindow::on_checkBox_dq_curr_target_stateChanged(int arg1)
{
    CheckSelectedBox(ui->checkBox_dq_curr_target, (arg1 > 0)?true:false);
}

void MainWindow::on_checkBox_svpwm_stateChanged(int arg1)
{
    CheckSelectedBox(ui->checkBox_svpwm, (arg1 > 0)?true:false);
}


void MainWindow::on_checkBox_dc_curr_stateChanged(int arg1)
{
    CheckSelectedBox(ui->checkBox_dc_curr, (arg1 > 0)?true:false);
}

void MainWindow::on_spinAxesMin_valueChanged(int arg1)
{
    ui->plot->yAxis->setRangeLower (arg1);
    ui->plot->replot();
}


void MainWindow::on_spinAxesMax_valueChanged(int arg1)
{
    ui->plot->yAxis->setRangeUpper (arg1);
    ui->plot->replot();
}


void MainWindow::on_spinYStep_valueChanged(int arg1)
{
    ui->plot->yAxis->ticker()->setTickCount(arg1);
    ui->plot->replot();
    ui->spinYStep->setValue(ui->plot->yAxis->ticker()->tickCount());
}


void MainWindow::on_spinPoints_valueChanged(int arg1)
{
    Q_UNUSED(arg1)
    if (plotMan->plot_points == 0) {
        ui->plot->xAxis->setRange (plotMan->plot_points, ui->spinPoints->value());
    }else{
        if (plotMan->b_start) {
            ui->plot->xAxis->setRange (plotMan->plot_points - ui->spinPoints->value(), plotMan->plot_points);
        }else {
            ui->plot->xAxis->setRange(ui->plot->xAxis->range().center() - ui->spinPoints->value()/2, ui->plot->xAxis->range().center() + ui->spinPoints->value()/2);
        }
    }
    ui->plot->replot();
}

void MainWindow::OnMouse_wheel_in_plot (QWheelEvent *event)
{
  QWheelEvent inverted_event = QWheelEvent(event->posF(), event->globalPosF(),
                                           -event->pixelDelta(), -event->angleDelta(),
                                           0, Qt::Vertical, event->buttons(), event->modifiers());
  QApplication::sendEvent (ui->spinPoints, &inverted_event);
}

void MainWindow::onMouseMoveInPlot(QMouseEvent *event)
{
    int xx = int(ui->plot->xAxis->pixelToCoord(event->x()));
    int yy = int(ui->plot->yAxis->pixelToCoord(event->y()));
    QString coordinates("X: %1 Y: %2");
    coordinates = coordinates.arg(xx).arg(yy);
    ui->statusBar->showMessage(coordinates);
}

void MainWindow::onMouseDoubleClick(QMouseEvent *event){
    Q_UNUSED(event);
    plotMan->b_start = !plotMan->b_start;
}

void MainWindow::channel_selection (void)
{
    /* synchronize selection of graphs with selection of corresponding legend items */
     for (int i = 0; i < ui->plot->graphCount(); i++)
       {
         QCPGraph *graph = ui->plot->graph(i);
         QCPPlottableLegendItem *item = ui->plot->legend->itemWithPlottable (graph);
         if (item->selected())
           {
             item->setSelected (true);
   //          graph->set (true);
           }
         else
           {
             item->setSelected (false);
     //        graph->setSelected (false);
           }
       }
}

void MainWindow::legend_double_click(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
{
    Q_UNUSED (legend)
    Q_UNUSED(event)
    /* Only react if item was clicked (user could have clicked on border padding of legend where there is no item, then item is 0) */
    if (item)
      {
        QCPPlottableLegendItem *plItem = qobject_cast<QCPPlottableLegendItem*>(item);
        bool ok;
        QString newName = QInputDialog::getText (this, "Change channel name", "New name:", QLineEdit::Normal, plItem->plottable()->name(), &ok, Qt::Popup);
        if (ok)
          {
            plItem->plottable()->setName(newName);
            ui->plot->replot();
          }
      }
}

void MainWindow::on_pushButton_AutoScale_clicked()
{
    ui->plot->yAxis->rescale(true);
    ui->spinAxesMax->setValue(int(ui->plot->yAxis->range().upper) + int(ui->plot->yAxis->range().upper*0.1));
    ui->spinAxesMin->setValue(int(ui->plot->yAxis->range().lower) + int(ui->plot->yAxis->range().lower*0.1));
}




void MainWindow::on_pushButton_m_start_clicked()
{
    if (mc->StartRun(true)){
        ShowMessage("启动成功");
    }else {
        ShowMessage("启动失败", Qt::red);
    }
}


void MainWindow::on_pushButton_m_stop_clicked()
{
    if (mc->StartRun(false)){
        ShowMessage("停止成功");
    }else {
        ShowMessage("停止失败", Qt::red);
    }
}

void MainWindow::on_checkBox_debug_stateChanged(int arg1)
{
    Q_UNUSED(arg1);
    //mc->enableLog(arg1>0);
}

//零位置对齐
void MainWindow::on_pushButton_D_Aligne_clicked()
{
    if(ui->lineEdit_D_aligne->text().isEmpty()){
        ShowMessage("请输入电压", Qt::red);
        return;
    }
    int vd = ui->lineEdit_D_aligne->text().toFloat();
    if (!open_force) {
        open_force = mc->ForceRunning(vd, 0);
    }else {
        open_force = !mc->ForceRunning(0, 0);
    }
    if (open_force) {
        ui->pushButton_D_Aligne->setText("停止D轴对齐");
        ui->pushButton_D_turn->setEnabled(false);
    }else {
        ui->pushButton_D_Aligne->setText("强制D轴对齐");
        ui->pushButton_D_turn->setEnabled(true);
    }
}

//开环强拖
void MainWindow::on_pushButton_D_turn_clicked()
{
    if(ui->lineEdit_D_turn->text().isEmpty()){
        ShowMessage("请输入电压", Qt::red);
        return;
    }
    int vd = ui->lineEdit_D_turn->text().toInt();
    int rpm = ui->lineEdit_D_rpm->text().toInt();
    if (!open_force) {
        open_force = mc->ForceRunning(vd, rpm);
    }else {
        open_force = !mc->ForceRunning(0, 0);
    }
    qDebug() << "Force RPM=" << rpm;
    if (open_force) {
        ui->pushButton_D_turn->setText("停止D轴电压转动");
        ui->pushButton_D_Aligne->setEnabled(false);
    }else {
        ui->pushButton_D_turn->setText("给定D轴电压转动");
        ui->pushButton_D_Aligne->setEnabled(true);
    }
}

//hall或者encoder零位置校准
void MainWindow::on_pushButton_enc_zero_cali_clicked()
{

}

void MainWindow::on_pushButton_ctrlmode_clicked()
{
    QString mode = ui->comboBox_mode->currentText();
    if (mc->SetCtrlMode(mode)) {
        ShowMessage("控制模式设置成功");
        return;
    }
    ShowMessage("控制模式设置失败", Qt::red);
}

void MainWindow::on_lineEdit_input_vel_returnPressed()
{
    if (mc->mode != Enum::Velocity) {
        return;
    }
    int value = ui->lineEdit_input_vel->text().toInt();
    qDebug() << "set target velocity " << value;
    mc->SetTargetVelocity(value);
}

void MainWindow::on_lineEdit_Mot_Enc_off_returnPressed(){
    float off = ui->lineEdit_Mot_Enc_off->text().toFloat();
    qDebug() << "set hall offset:" << off;
    //mc->SetHallOffset(off);
}


void MainWindow::on_checkBox_fw_en_stateChanged(int arg1)
{
    Q_UNUSED(arg1);
}

void MainWindow::ShowEditText(QLineEdit *edit, float v){
    edit->setText(QString::number(v));
}
void MainWindow::ShowEditText(QLineEdit *edit, s16 v){
    edit->setText(QString::number(v));
}
void MainWindow::ShowEditText(QLineEdit *edit, u16 v){
    edit->setText(QString::number(v));
}
void MainWindow::ShowEditText(QLineEdit *edit, bool v){
    edit->setText(QString::number(v));
}
void MainWindow::ShowEditText(QLineEdit *edit, u8 v){
    edit->setText(QString::number(v));
}

s16 MainWindow::getValue_s16(QLineEdit *edit){
    return edit->text().toInt();
}

u16 MainWindow::getValue_u16(QLineEdit *edit){
    return edit->text().toUShort();
}

u8 MainWindow::getValue_u8(QLineEdit *edit){
    return edit->text().toUShort();
}

float MainWindow::getValue_float(QLineEdit *edit){
    return edit->text().toFloat();
}

void MainWindow::UpdateMCParamToUI(){
    //update motor params
    ShowEditText(ui->lineEdit_Rs, mc->mc_conf.m.rs);
    ShowEditText(ui->lineEdit_Ld, mc->mc_conf.m.ld);
    ShowEditText(ui->lineEdit_Lq, mc->mc_conf.m.lq);
    ShowEditText(ui->lineEdit_Poles, mc->mc_conf.m.poles);
    ShowEditText(ui->lineEdit_Flux, mc->mc_conf.m.flux);
    ShowEditText(ui->lineEdit_J, mc->mc_conf.m.J);
    ShowEditText(ui->lineEdit_fw_id, mc->mc_conf.m.max_fw_id);
    ShowEditText(ui->lineEdit_Mot_Enc_off, mc->mc_conf.m.encoder_offset);
    ShowEditText(ui->lineEdit_mot_enc_pll, mc->mc_conf.m.enc_pll_band);
    ShowEditText(ui->lineEdit_Mot_Max_rpm, mc->mc_conf.m.max_rpm);
    ui->checkBox_fw_en->setChecked(mc->mc_conf.m.fw_enable==1);

    //update board
    ShowEditText(ui->lineEdit_Board_vbus_max, mc->mc_conf.b.vbus_voltage_max);
    ShowEditText(ui->lineEdit_Board_vbus_min, mc->mc_conf.b.vbus_voltage_min);
    ShowEditText(ui->lineEdit_Board_vbus_curr_max, mc->mc_conf.b.vbus_curr_max);
    ShowEditText(ui->lineEdit_Board_phase_curr_max, mc->mc_conf.b.phase_curr_max);
    ShowEditText(ui->lineEdit_Board_brake_resistor, mc->mc_conf.b.brake_resistance);
    ShowEditText(ui->lineEdit_Board_regen_curr_max, mc->mc_conf.b.max_regen_current);
    ShowEditText(ui->lineEdit_Board_vbus_ramp_start, mc->mc_conf.b.dc_bus_overvoltage_ramp_start);
    ShowEditText(ui->lineEdit_Board_vbus_ramp_end, mc->mc_conf.b.dc_bus_overvoltage_ramp_end);
    ui->checkBox_brake_resistor->setChecked(mc->mc_conf.b.enable_brake_resistor==1);
    ui->checkBox_vbus_over_vol->setChecked(mc->mc_conf.b.enable_dc_bus_overvoltage_ramp==1);

    //update controller
    ShowEditText(ui->lineEdit_Ctrl_ebrk_torque_max, mc->mc_conf.c.max_ebrk_torque);
    ShowEditText(ui->lineEdit_Ctrl_loop_bandwith, mc->mc_conf.c.dq_loop_bandwith);
    ui->checkBox_ctrl_pid_neg_trq_en->setChecked(mc->mc_conf.c.b_allow_pid_neg_torque==1);
    ui->checkBox_acs_enable->setChecked(mc->mc_conf.c.b_asc_enable);
    ShowEditText(ui->lineEdit_acs_vel, mc->mc_conf.c.asc_min_vel);
    ui->checkBox_regen_forbiden->setChecked(mc->mc_conf.c.b_regen_forbidden);
    ShowEditText(ui->lineEdit_regen_forbit_torque, mc->mc_conf.c.regen_forbinden_min_torque);
    ShowEditText(ui->lineEdit_regen_forbit_vel, mc->mc_conf.c.regen_forbinden_min_vel);
    qDebug() << "show regen forbinden vel" << mc->mc_conf.c.regen_forbinden_min_vel;

    ShowEditText(ui->lineEdit_vel_kp, mc->mc_conf.c.pid[PID_Vel_ID].kp);
    ShowEditText(ui->lineEdit_vel_ki, mc->mc_conf.c.pid[PID_Vel_ID].ki);
    ShowEditText(ui->lineEdit_vel_kb, mc->mc_conf.c.pid[PID_Vel_ID].kd);
}


void MainWindow::UpdateMCParamFromUI(){
    //update motor params
    mc->mc_conf.m.rs = getValue_float(ui->lineEdit_Rs);
    mc->mc_conf.m.ld = getValue_float(ui->lineEdit_Ld);
    mc->mc_conf.m.lq = getValue_float(ui->lineEdit_Lq);
    mc->mc_conf.m.poles = getValue_u8(ui->lineEdit_Poles);

    mc->mc_conf.m.flux = getValue_float(ui->lineEdit_Flux);
    mc->mc_conf.m.J = getValue_float(ui->lineEdit_J);
    mc->mc_conf.m.max_fw_id = getValue_s16(ui->lineEdit_fw_id);
    mc->mc_conf.m.encoder_offset = getValue_float(ui->lineEdit_Mot_Enc_off);
    mc->mc_conf.m.enc_pll_band = getValue_s16(ui->lineEdit_mot_enc_pll);
    mc->mc_conf.m.max_rpm = getValue_s16(ui->lineEdit_Mot_Max_rpm);
    mc->mc_conf.m.fw_enable = ui->checkBox_fw_en->isChecked();

    //update board
    mc->mc_conf.b.vbus_voltage_max = getValue_s16(ui->lineEdit_Board_vbus_max);
    mc->mc_conf.b.vbus_voltage_min = getValue_s16(ui->lineEdit_Board_vbus_min);
    mc->mc_conf.b.vbus_curr_max = getValue_s16(ui->lineEdit_Board_vbus_curr_max);
    mc->mc_conf.b.phase_curr_max = getValue_s16(ui->lineEdit_Board_phase_curr_max);
    mc->mc_conf.b.brake_resistance = getValue_float(ui->lineEdit_Board_brake_resistor);
    mc->mc_conf.b.max_regen_current = getValue_float(ui->lineEdit_Board_regen_curr_max);
    mc->mc_conf.b.dc_bus_overvoltage_ramp_start = getValue_float(ui->lineEdit_Board_vbus_ramp_start);
    mc->mc_conf.b.dc_bus_overvoltage_ramp_end = getValue_float(ui->lineEdit_Board_vbus_ramp_end);
    mc->mc_conf.b.enable_brake_resistor = ui->checkBox_brake_resistor->isChecked();
    mc->mc_conf.b.enable_dc_bus_overvoltage_ramp = ui->checkBox_vbus_over_vol->isChecked();

    //update controller
    mc->mc_conf.c.max_ebrk_torque = getValue_s16(ui->lineEdit_Ctrl_ebrk_torque_max);
    mc->mc_conf.c.dq_loop_bandwith = getValue_s16(ui->lineEdit_Ctrl_loop_bandwith);
    mc->mc_conf.c.b_allow_pid_neg_torque = ui->checkBox_ctrl_pid_neg_trq_en->isChecked();
    mc->mc_conf.c.b_asc_enable = ui->checkBox_acs_enable->isChecked();
    mc->mc_conf.c.asc_min_vel = getValue_s16(ui->lineEdit_acs_vel);
    mc->mc_conf.c.b_regen_forbidden = ui->checkBox_regen_forbiden->isChecked();
    mc->mc_conf.c.regen_forbinden_min_torque = getValue_s16(ui->lineEdit_regen_forbit_torque);
    mc->mc_conf.c.regen_forbinden_min_vel = getValue_s16(ui->lineEdit_regen_forbit_vel);

    mc->mc_conf.c.pid[PID_Vel_ID].kp = getValue_float(ui->lineEdit_vel_kp);
    mc->mc_conf.c.pid[PID_Vel_ID].ki = getValue_float(ui->lineEdit_vel_ki);
    mc->mc_conf.c.pid[PID_Vel_ID].kd = getValue_float(ui->lineEdit_vel_kb);
}

void MainWindow::on_pushButton_clicked()
{
    box->ResetDevice(mc->DeviceAddress());
}


void MainWindow::on_pushButton_vdq_clicked()
{
    mc->SetDqVoltage(getValue_u8(ui->lineEdit_vd), getValue_u8(ui->lineEdit_vq));
}


void MainWindow::on_pushButton_torque_clicked()
{
    mc->SetTargetTorque(getValue_s16(ui->lineEdit_torque));
}


void MainWindow::on_pushButton_dqcurr_clicked()
{
    mc->SetDqCurrent(getValue_s16(ui->lineEdit_id), getValue_s16(ui->lineEdit_iq));
}

